#include <cmath>
#include "MLProgressbar.h"
#include "NotesTrack.h"

NotesTrack::NotesTrack(
	NoteStream& stream,
	int frame_size_x, int frame_size_y,
	double frame_rate,
	size_t tracks_num,
	size_t track_index,
	Color raw_color,
	Byte alpha,
	double play_speed,
	GLuint glsl,
	GLuint mix_glsl,
	int record_radius,
	double border_brightness,
	double center_brightness,
	double border_radius,
	double middle_color_loc
) {
	printf("正在初始化音符轨道[%zu/%zu]……\n", track_index + 1, tracks_num);
	MLProgressbar progressbar(stream.notes_num, "初始化进度");
	_start_angle = new float[stream.notes_num];
	_end_angle = new float[stream.notes_num];
	_r = new uint8_t[stream.notes_num];
	_g = new uint8_t[stream.notes_num];
	_b = new uint8_t[stream.notes_num];
	_start_duration = new size_t[stream.notes_num];
	_end_duration = new size_t[stream.notes_num];
	for (size_t i = 0; i < stream.notes_num; i++) {
		Size2 duration = {
			.x = (size_t)round(stream.notes.at(i, 0)),
			.y = (size_t)round(stream.notes.at(i, 1))
		};
		if (duration.x == duration.y)continue;
		size_t velocity = (size_t)stream.notes.at(i, 2);
		if (velocity == 0)continue;
		Note note(
			tracks_num,
			track_index,
			stream.pitch_range,
			stream.pitch_min,
			(size_t)stream.notes.at(i, 3),
			velocity,
			duration,
			raw_color
		);
		progressbar.update();
		_start_angle[i] = note.pitch_start_angle;
		_end_angle[i] = note.pitch_end_angle;
		_r[i] = note.note_color.x;
		_g[i] = note.note_color.y;
		_b[i] = note.note_color.z;
		_start_duration[i] = (size_t)((double)note.note_duration.x * play_speed / frame_rate + record_radius);
		_end_duration[i] = (size_t)((double)note.note_duration.y * play_speed / frame_rate + record_radius - 2);
	}
	_center_x = frame_size_x / 2;
	_center_y = frame_size_y / 2;
	_max_radius = sqrt(_center_x * _center_x + _center_y * _center_y);
	_frame_size_x = frame_size_x; _frame_size_y = frame_size_y;
	_play_speed = play_speed / frame_rate;
	_glsl = glsl;
	_mix_glsl = mix_glsl;
	_notes_count = stream.notes_num;
	_sharedFB = Drawer::initSharedFramebuffer(frame_size_x, frame_size_y);
	_double_sectors = Drawer::initDoubleSector(frame_size_x, frame_size_y, _start_angle, _end_angle, _r, _g, _b, alpha, _start_duration, _end_duration, _notes_count, border_brightness, center_brightness, border_radius, middle_color_loc);
	_end_radius = record_radius;
}


void NotesTrack::clear() {
	_double_sectors.clear();
	delete[] _start_angle;
	delete[] _end_angle;
	delete[] _r;
	delete[] _g;
	delete[] _b;
	delete[] _start_duration;
	delete[] _end_duration;
}

void NotesTrack::get_frame(size_t frame_index, MLFrame& frame) {
	Utils::clearFrame(_sharedFB.msaaFBO);
	Drawer::drawDoubleSector(_glsl, _double_sectors, frame_index * _play_speed, _sharedFB, _end_radius, _max_radius,
	                         _draw_start);
	frame.mix(_sharedFB.resolveFBO, _sharedFB.colorTex, _sharedFB.colorRBO, _mix_glsl);
}
